

package control;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import model.Account;
import model.Share;
import model.Time;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import view.AbstractShareView;
import org.jdesktop.application.Action;
import org.jdesktop.application.Application;
import org.jdesktop.application.ResourceMap;
/**
 * ChartController.java
 * @author Diego Schmaedech
 * @version 1.0
 * @since Release Beta
 * @link  http://code.google.com/p/economylabs
 * Created on August 2, 2008, 2:34 AM
 */
public class ChartController extends AbstractShareView {

              
    private XYSeries series1;
    private double incrementSerie1;
    private XYSeries series2;
    private double incrementSerie2;
    private XYSeries series3;
    private double incrementSerie3;
    private XYSeries series4;
    private double incrementSerie4;
    private XYSeries series5;
    private double incrementSerie5;
    private XYSeries series6; 
    private double incrementSerie6;         
    private String timestamp; 
    private int interval;
    private Timer timerControl;     
    private int countForward=0;        
    private javax.swing.JButton jbForward;
    private javax.swing.JButton jbPause;
    private javax.swing.JButton jbPlay;    
    public javax.swing.JPanel jpControlButtons;
    private Calendar calendar = Calendar.getInstance();
    private SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss");
    public javax.swing.JPanel jpAux; 
    
    private Timer timerClock;
    private int chronometer;     
    private Timer timerForward;
    private int timerController=0;      
    private boolean simPaused = false; 
    private Account account;     
    private Share share;
    private Time time;
     
    public ChartController( Share controlledShare, Account controlledAccount, Time controlledTime ) {
        super( controlledShare );
        
        setAccount(controlledAccount);
        setShare(controlledShare);
        setTime(controlledTime);     
        initComponents();
        setInterval(getShare().getInterval());
        this.countForward=0; 
         
        final XYSeriesCollection dataset = new XYSeriesCollection();
         
        setSeries1( new XYSeries(getShare().getShareName(0)));
        setSeries2( new XYSeries(getShare().getShareName(1)));
        setSeries3( new XYSeries(getShare().getShareName(2)));
        setSeries4( new XYSeries(getShare().getShareName(3)));
        setSeries5( new XYSeries(getShare().getShareName(4)));
        setSeries6( new XYSeries(getShare().getShareName(5)));
        dataset.addSeries(getSeries1());
        dataset.addSeries(getSeries2());
        dataset.addSeries(getSeries3());
        dataset.addSeries(getSeries4());
        dataset.addSeries(getSeries5());
        dataset.addSeries(getSeries6());
        
        final JFreeChart chart = createChart(dataset);
        final ChartPanel chartPanel = new ChartPanel(chart);
          //chartPanel.add(jpControlButtons);
        
        //chartPanel.setLayout( new FlowLayout() );
        chartPanel.setPreferredSize( new Dimension(560, 380) );
        //chartPanel.setBackground(new  Color(0, 254, 254));
       // jpAux.setLayout( new FlowLayout() );
        jpAux.setPreferredSize( new Dimension(565, 465) );
        jpAux.add(chartPanel); 
                
        jpAux.setBackground(new Color(254, 254, 254));
        ResourceMap resourceMap = Application.getInstance(expecon.ExpEconApp.class).getContext().getResourceMap(ChartController.class);
        setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("borderGraphic.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("DejaVu Sans", 1, 13), new java.awt.Color(113, 196, 243))); // NOI18N
        //setPreferredSize(new Dimension(596, 600));
        jpAux.add(jpControlButtons); 
        
        add(jpAux); 
        
       // startJokerTimer();
    }
     
    private void initComponents(){
        jbPlay = new javax.swing.JButton();
        jbForward = new javax.swing.JButton();
        jbPause = new javax.swing.JButton();
        jpControlButtons = new javax.swing.JPanel();
        jpAux = new javax.swing.JPanel();
        ResourceMap resourceMap = Application.getInstance(expecon.ExpEconApp.class).getContext().getResourceMap(ChartController.class);
       
        jpControlButtons.setBackground(resourceMap.getColor("jpControlButtons.background")); // NOI18N
        jpControlButtons.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("jpControlButtons.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, resourceMap.getFont("jpControlButtons.border.titleFont"), resourceMap.getColor("jpControlButtons.border.titleColor"))); // NOI18N
        jpControlButtons.setName("jpControlButtons"); // NOI18N
        jpControlButtons.setPreferredSize(new java.awt.Dimension(460, 70));

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(expecon.ExpEconApp.class).getContext().getActionMap(ChartController.class, this);
        jbPlay.setAction(actionMap.get("play")); // NOI18N
        jbPlay.setFont(resourceMap.getFont("jbPlay.font")); // NOI18N
        jbPlay.setIcon(resourceMap.getIcon("jbPlay.icon")); // NOI18N
        jbPlay.setText(resourceMap.getString("jbPlay.text")); // NOI18N
        jbPlay.setName("jbPlay"); // NOI18N
        jbPlay.setPreferredSize(new java.awt.Dimension(120, 40));

        jbForward.setAction(actionMap.get("forward")); // NOI18N
        jbForward.setFont(resourceMap.getFont("jbForward.font")); // NOI18N
        jbForward.setIcon(resourceMap.getIcon("jbForward.icon")); // NOI18N
        jbForward.setText(resourceMap.getString("jbForward.text")); // NOI18N
        jbForward.setEnabled(false);
        jbForward.setName("jbForward"); // NOI18N
        jbForward.setPreferredSize(new java.awt.Dimension(120, 40));

        jbPause.setAction(actionMap.get("pause")); // NOI18N
        jbPause.setIcon(resourceMap.getIcon("jbPause.icon")); // NOI18N
        jbPause.setText(resourceMap.getString("jbPause.text")); // NOI18N
        jbPause.setEnabled(false);
        jbPause.setName("jbPause"); // NOI18N
        jbPause.setPreferredSize(new java.awt.Dimension(120, 40));

        javax.swing.GroupLayout jpControlButtonsLayout = new javax.swing.GroupLayout(jpControlButtons);
        jpControlButtons.setLayout(jpControlButtonsLayout);
        jpControlButtonsLayout.setHorizontalGroup(
            jpControlButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpControlButtonsLayout.createSequentialGroup()
                .addGap(36, 36, 36)
                .addComponent(jbPlay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbForward, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbPause, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(36, 36, 36))
        );
        jpControlButtonsLayout.setVerticalGroup(
            jpControlButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpControlButtonsLayout.createSequentialGroup()
                .addGroup(jpControlButtonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbPlay, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jbForward, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jbPause, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }
  
    private JFreeChart createChart(final XYDataset dataset) {
        JFreeChart result = ChartFactory.createXYLineChart(
            "Periodo X Preço",
            "Periodo",
            "Preço",
            dataset,
            PlotOrientation.VERTICAL,
            true,
            false,
            false
        );
        
        
        final XYPlot plot = result.getXYPlot();
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
         
        renderer.setSeriesShapesVisible(1, true);        
        renderer.setSeriesStroke(0, new BasicStroke(2.0f));
        renderer.setSeriesStroke(1, new BasicStroke(2.0f));
        renderer.setSeriesStroke(2, new BasicStroke(2.0f));
        renderer.setSeriesStroke(3, new BasicStroke(2.0f));
        renderer.setSeriesStroke(4, new BasicStroke(2.0f));
        renderer.setSeriesStroke(5, new BasicStroke(2.0f));                 
        plot.setRenderer(renderer);         
        ValueAxis axis = plot.getDomainAxis();                  
        axis.setRange(1, getShare().getMaxPeriod());
        axis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 
        axis = plot.getRangeAxis(); 
        axis.setAutoRange(true);
        return result;
    }
    
    @Action
    public void play() {
        jbForward.setEnabled(true);
        jbPause.setEnabled(true);
        
        if(simPaused==false){
            jbPlay.setEnabled(false);
            getTime().play(); 
            getAccount().play();
            getShare().play();
            startClock(); 
            updatePlotSeries();
              
            if(getTime().getPeriodsForward()!=0){
                timerController=getTime().getPeriodsForward();
                timerForward = new Timer(0, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                         timerController--;
                         forward();
                         if(timerController==0){
                             timerForward.stop();
                         }
                     }

                });
                timerForward.start(); 
            } 
        }else{            
            getTime().play(); 
            getAccount().replay();
            getShare().play();
            jbPlay.setText("<html>Começar</html>"); 
            timerClock.start(); 
            updatePlotSeries();
            jbPlay.setEnabled(false);
        }
        
    }

    @Action
    public void forward() {
        
        this.countForward++;
        if(countForward==getTime().getMaxPeriod()){
            pauseClock();
             
            jbPlay.setEnabled(false);
            jbPause.setEnabled(false);
            jbForward.setEnabled(false); 
           
            getTime().stop();
            getShare().stop();
            getAccount().stop();
             //notas do jocker-----        
            //String ans;
            //ans = JOptionPane.showInputDialog(null, "<html>Acabaram os periodos para esta simulação.<br />" +
                   // " Agradeçemos sua colaboração em nossos estudos.<br />" +
                   // "Para salvar os dados da sua participação digite <i>sim</i> no campo abaixo e acione OK</html>","Mensagem!",JOptionPane.INFORMATION_MESSAGE);
            //if(ans == null || ans.equals("")){
              // System.exit(0);
            //}
            //if(ans.equals("sim")){
               getAccount().saveAs(); 
            //}
          
        //fim do jocker------- 
            
        }else{
            
            getTime().forward(getTime().getPeriod(), getTime().getTimestamp());
            getShare().forward(getTime().getPeriod());
            getAccount().forward(getTime().getPeriod(), getShare().getShareTable());

            updatePlotSeries();
            restartClock();
        }
    }

    @Action
    public void pause() {
        jbPlay.setEnabled(true);
        jbPlay.setText("<html>Retornar</html>");       
        jbPause.setEnabled(false);
        jbForward.setEnabled(false);
            
        getTime().stop();
        getShare().stop();
        getAccount().stop();
        
        pauseClock();
        
        JOptionPane.showMessageDialog(null, "<html>Para continuar a simulação acione o botão <i>Retornar</i></html>");
        
    }
   
    private void restartClock(){            
        chronometer = 0;
        timerClock.start(); 
    }
     
    private void pauseClock(){
        //chronometer = 0;
        simPaused=true;
        getTime().timerCounter(chronometer);
        timerClock.stop(); 
        
    }
         
    private void startClock(){
          
        timerClock = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                if (chronometer == getTime().getInterval()) { 
                    
                    forward();                      
                    restartClock(); 
                    
                }
                 
                chronometer++;
                getTime().setTimestamp(getStringClock());
                getTime().timerCounter(chronometer);
                 
                }
        });
        
        chronometer = 0;
        timerClock.start(); 
          
    }
     //Metodos auxiliares, nao modifique
    private String getStringClock() {
          
        calendar.setTimeInMillis(System.currentTimeMillis());
        String strClock = dateFormat.format(calendar.getTime());
        return strClock;
    }
    
    public void startJokerTimer() {
       
        incrementSerie1 = getShare().getVariation(0); 
        incrementSerie2 = getShare().getVariation(1); 
        incrementSerie3 = getShare().getVariation(2); 
        incrementSerie4 = getShare().getVariation(3); 
        incrementSerie5 = getShare().getVariation(4); 
        incrementSerie6 = getShare().getVariation(5); 
        timerControl = new Timer(0, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                               
               updatePlotSeries();
               incrementSerie1 = (getShare().getVariation(0)  ); 
               incrementSerie2 = (getShare().getVariation(1)  );
               incrementSerie3 = (getShare().getVariation(2)  );
               incrementSerie4 = (getShare().getVariation(3)  );
               incrementSerie5 = (getShare().getVariation(4)  );
               incrementSerie6 = (getShare().getVariation(5)  );
                        
            }
                
        });
        
         
        timerControl.start(); 
        timerControl.stop(); 
    }
    
    private void updatePlotSeries( ){                
        
        incrementSerie1 = getShare().getPurchasePrice(0); 
        incrementSerie2 = getShare().getPurchasePrice(1); 
        incrementSerie3 = getShare().getPurchasePrice(2); 
        incrementSerie4 = getShare().getPurchasePrice(3); 
        incrementSerie5 = getShare().getPurchasePrice(4); 
        incrementSerie6 = getShare().getPurchasePrice(5);
          
        getSeries1().add(getShare().getCurrentPeriod(), incrementSerie1 );
        getSeries2().add(getShare().getCurrentPeriod(), incrementSerie2 );
        getSeries3().add(getShare().getCurrentPeriod(), incrementSerie3 );
        getSeries4().add(getShare().getCurrentPeriod(), incrementSerie4 );
        getSeries5().add(getShare().getCurrentPeriod(), incrementSerie5 );
        getSeries6().add(getShare().getCurrentPeriod(), incrementSerie6 );
        
    }
    
    @Override
    protected void updateDisplay() {
          
    }  
     

     //do not modify this
    public void setTime(Time time) {
        this.time = time;
    }
  
    public void setAccount(Account account) {
        this.account = account;
    }

    public void setShare(Share share) {
        this.share = share;
    }
 
    @Override
    public Share getShare() {
        return share;
    }

    public Account getAccount() {
        return account;
    }

    public Time getTime() {
        return time;
    }
     
 

    public XYSeries getSeries1() {
        return series1;
    }

    public void setSeries1(XYSeries series1) {
        this.series1 = series1;
    }

    public XYSeries getSeries2() {
        return series2;
    }

    public void setSeries2(XYSeries series2) {
        this.series2 = series2;
    }

    public XYSeries getSeries3() {
        return series3;
    }

    public void setSeries3(XYSeries series3) {
        this.series3 = series3;
    }

    public XYSeries getSeries4() {
        return series4;
    }

    public void setSeries4(XYSeries series4) {
        this.series4 = series4;
    }

    public XYSeries getSeries5() {
        return series5;
    }

    public void setSeries5(XYSeries series5) {
        this.series5 = series5;
    }

    public XYSeries getSeries6() {
        return series6;
    }

    public void setSeries6(XYSeries series6) {
        this.series6 = series6;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
    
    public int getInterval() {
        return interval;
    }

    public void setInterval(int interval) {
        this.interval = interval;
    }
}